#include "stdafx.h"
#include <boost/test/auto_unit_test.hpp>
#include <sstream>
#include "detail/bmock_out_raw_mem_ptr.hpp"
#include "detail/bmock_test_control_tools.hpp"
#include "bmock_util.hpp"
#include <algorithm>

namespace bmock {
	static const control_tools_ptr tl(new test_control_tools());
	static const char              name[]   = "arg";
	static const unsigned char     val1[]   = {0x00,0x01,0x02,0xF1,0xF2};
	static const size_t            LEN      = sizeof(val1);
	static const std::string            s_val1 = "000102F1F2";

	BOOST_AUTO_TEST_CASE(test_out_raw_mem_ptr_get_value) {
		const in_out_raw_mem_descr<unsigned char> rm = out_raw_mem(val1,LEN);
		const arg_val_ptr p_val(new out_raw_mem_ptr(name
			,(unsigned char *)rm
			,raw_mem(val1,LEN+100)));
		arg_checker       ac(tl);
		const arg_val_str expected("",s_val1);

		ac.set_location(location(__FILE__,__LINE__+1));
		BOOST_CHECK_EQUAL(expected,p_val->get_value(ac));
	}

	BOOST_AUTO_TEST_CASE(test_out_raw_mem_ptr_update) {
		const in_out_raw_mem_descr<unsigned char> rm = out_raw_mem(val1,LEN);
		unsigned char     val2[LEN];
		const arg_val_ptr p_val(new out_raw_mem_ptr(name
			,rm.get_ptr()
			,raw_mem(val2,LEN)));
		arg_checker       al(tl);
		const arg_val_str expected("",s_val1);

		std::fill_n(val2,LEN,0);
		al.set_location(location(__FILE__,__LINE__+1));
		BOOST_CHECK_NO_THROW(p_val->update(al,expected));
		BOOST_CHECK_EQUAL(LEN,mismatch_at(val1,val1+LEN,val2));
	}

	BOOST_AUTO_TEST_CASE(test_out_raw_mem_ptr_print) {
		const in_out_raw_mem_descr<unsigned char> rm = out_raw_mem(val1,LEN);
		unsigned char     val2[LEN];
		const arg_val_ptr p_val(new out_raw_mem_ptr(name
			,rm.get_ptr()
			,raw_mem(val2,LEN)));
		const std::string      expected = std::string("OUT(")+out_arg_val::UNKNOWN+")";
		std::ostringstream        os;

		std::copy(val1,val1+LEN,val2);
		BOOST_CHECK_NO_THROW(p_val->print(os));
		BOOST_CHECK_EQUAL(expected,os.str());
	}

	struct stam_out_raw_mem_ptr: public out_raw_mem_ptr {
		stam_out_raw_mem_ptr(const char *const n,const void *exp,const raw_mem &tar)
			:out_raw_mem_ptr(n,exp,tar)

		{}
		~stam_out_raw_mem_ptr() {}

	};

	BOOST_AUTO_TEST_CASE(test_out_raw_mem_ptr_operator) {
		const char *const n=new char [2];
		const void *exp=new char [2];
		const raw_mem tar;
		const stam_out_raw_mem_ptr p_val(n,exp,tar);
		stam_out_raw_mem_ptr p_val1(n,exp,tar);

		BOOST_CHECK_NO_THROW(p_val1=p_val);

		delete[]n;
		delete[](const char*)exp;
	}
}
